import entity.Group;
import enums.ResponseType;
import request.group.relation.GroupListRequest;
import request.relation.FriendListRequest;
import response.Response;
import response.group.relation.GroupListResponse;
import response.relation.FriendListResponse;

import javax.swing.*;
import java.awt.*;
import java.util.Enumeration;
import java.util.List;
import java.util.UUID;

public class ContactsView extends JFrame {

    private JLabel nameLabel;
    private JLabel groupNameLabel=new JLabel("群名:");
    private JLabel groupFriendLabel=new JLabel("好友名:");
    private SpringLayout springLayout = new SpringLayout();
    private SpringLayout groupSpringLayout=new SpringLayout();
    private JTabbedPane jTabbedPane=new JTabbedPane();
    private JPanel panel = new JPanel(springLayout);
    private JPanel groupPanel=new JPanel(groupSpringLayout);

    private JScrollPane scrollPane = new JScrollPane();
    private JScrollPane groupScrollPane=new JScrollPane();
    private JButton chatButton = new JButton("发起聊天");
    private JButton addFriendButton = new JButton("添加新好友");
    private JButton friendRequestButton = new JButton("查看好友请求");
    private JButton addGroupButton=new JButton("创建群聊");
    private JButton enterGroupButton=new JButton("进入群聊");
    private JTextField friendNameField = new JTextField();
    private JTextField groupNameField=new JTextField();
    private JTextField groupFriendNameField=new JTextField();

    private ContactsHandler contactsHandler = new ContactsHandler(this);

    private String hostUserName;
    private String guestUserName;
    private UUID groupid;
    private JList<String> jList;
    private JList<Group> groupJList;
    private List<String> usernameList;
    private List<Group> groupList;

    public ContactsView(String userName) {
        super("chatDistance Client");
        this.hostUserName = userName;
        nameLabel = new JLabel("Welcome: " + userName, SwingConstants.CENTER);
        setBounds(1550, 150, 300, 700);
        nameLabel.setFont(new Font("华文行楷", Font.PLAIN, 25));
        Font panelFont = new Font("楷体", Font.PLAIN, 15);
        friendNameField.setFont(panelFont);
        addFriendButton.setFont(panelFont);
        chatButton.setFont(panelFont);
        friendRequestButton.setFont(panelFont);
        friendRequestButton.addActionListener(contactsHandler);
        addFriendButton.addActionListener(contactsHandler);
        chatButton.addActionListener(contactsHandler);
        nameLabel.setPreferredSize(new Dimension(0, 40));
        friendNameField.setPreferredSize(new Dimension(200, 30));
        scrollPane.setPreferredSize(new Dimension(290, 450));
        jList = new JList<>(new DefaultListModel<>());
        jList.setFont(panelFont);
        jList.addListSelectionListener(e -> {
            if (!jList.getValueIsAdjusting()) {    //设置只有释放鼠标时才触发
                guestUserName = jList.getSelectedValue();
            }
        });
        scrollPane.setViewportView(jList);
        panel.add(scrollPane);
        panel.add(chatButton);
        panel.add(addFriendButton);
        panel.add(friendNameField);
        panel.add(friendRequestButton);

        springLayout.putConstraint(SpringLayout.WEST, friendNameField, 40, SpringLayout.WEST, scrollPane);
        springLayout.putConstraint(SpringLayout.NORTH, friendNameField, 20, SpringLayout.SOUTH, scrollPane);
        springLayout.putConstraint(SpringLayout.WEST, chatButton, 20, SpringLayout.WEST, scrollPane);
        springLayout.putConstraint(SpringLayout.NORTH, chatButton, 20, SpringLayout.SOUTH, friendNameField);
        springLayout.putConstraint(SpringLayout.WEST, addFriendButton, 50, SpringLayout.EAST, chatButton);
        springLayout.putConstraint(SpringLayout.NORTH, addFriendButton, 20, SpringLayout.SOUTH, friendNameField);
        springLayout.putConstraint(SpringLayout.NORTH, friendRequestButton, 10, SpringLayout.SOUTH, chatButton);
        springLayout.putConstraint(SpringLayout.WEST, friendRequestButton, 65, SpringLayout.WEST, chatButton);

        jTabbedPane.addTab("我的好友",panel);

        addGroupButton.setFont(panelFont);
        enterGroupButton.setFont(panelFont);
        groupFriendNameField.setFont(panelFont);
        groupNameField.setFont(panelFont);
        groupNameLabel.setFont(panelFont);
        groupFriendLabel.setFont(panelFont);
        addGroupButton.addActionListener(contactsHandler);
        enterGroupButton.addActionListener(contactsHandler);
        groupScrollPane.setPreferredSize(new Dimension(290, 450));
        groupNameField.setPreferredSize(new Dimension(200, 30));
        groupFriendNameField.setPreferredSize(new Dimension(200, 30));
        groupJList = new JList<>(new DefaultListModel<>());
        groupJList.setCellRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                Group group = (Group) value;
                setText(group.getName() + "("+ group.getUuid() +")");
                return component;
            }
        });
        groupJList.setFont(panelFont);
        refreshContactsView();
        groupJList.setFont(panelFont);
        groupJList.addListSelectionListener(e -> {
            if (!groupJList.getValueIsAdjusting()) {    //设置只有释放鼠标时才触发
                groupid=groupJList.getSelectedValue().getUuid();
            }
        });
        groupScrollPane.setViewportView(groupJList);
        groupPanel.add(groupScrollPane);
        groupPanel.add(addGroupButton);
        groupPanel.add(enterGroupButton);
        groupPanel.add(groupFriendNameField);
        groupPanel.add(groupNameField);
        groupPanel.add(groupNameLabel);
        groupPanel.add(groupFriendLabel);

        groupSpringLayout.putConstraint(SpringLayout.WEST,groupNameLabel,20,SpringLayout.WEST,groupScrollPane);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,groupNameLabel,20,SpringLayout.SOUTH,groupScrollPane);
        groupSpringLayout.putConstraint(SpringLayout.WEST,groupNameField,20,SpringLayout.EAST,groupNameLabel);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,groupNameField,0,SpringLayout.NORTH,groupNameLabel);
        groupSpringLayout.putConstraint(SpringLayout.WEST,groupFriendLabel,0,SpringLayout.WEST,groupNameLabel);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,groupFriendLabel,20,SpringLayout.SOUTH,groupNameLabel);
        groupSpringLayout.putConstraint(SpringLayout.WEST,groupFriendNameField,20,SpringLayout.EAST,groupFriendLabel);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,groupFriendNameField,0,SpringLayout.NORTH,groupFriendLabel);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,addGroupButton,20,SpringLayout.SOUTH,groupFriendLabel);
        groupSpringLayout.putConstraint(SpringLayout.WEST,addGroupButton,20,SpringLayout.WEST,groupFriendLabel);
        groupSpringLayout.putConstraint(SpringLayout.NORTH,enterGroupButton,0,SpringLayout.NORTH,addGroupButton);
        groupSpringLayout.putConstraint(SpringLayout.WEST,enterGroupButton,40,SpringLayout.EAST,addGroupButton);

        jTabbedPane.addTab("群聊",groupPanel);

        getContentPane().add(nameLabel, BorderLayout.NORTH);
        getContentPane().add(jTabbedPane);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
        detectFriendsChange();
    }

    private void detectFriendsChange() {
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                refreshContactsView();
            }
        }).start();
    }

    public String getUserName() {
        return this.hostUserName;
    }

    public String getGuestName() {
        return guestUserName;
    }

    public void refreshContactsView() {
        FriendListRequest friendListRequest = new FriendListRequest(hostUserName);
        Response response = ConnectionUtil.makeConnection(friendListRequest);
        if (response.getType().equals(ResponseType.FriendList)) {
            DefaultListModel<String> listModel = (DefaultListModel<String>) jList.getModel();
            FriendListResponse friendListResponse = (FriendListResponse) response;
            usernameList = friendListResponse.getUsernameList();
            boolean change = false;
            for (String username : usernameList) {
                if (listModel.contains(username)) {
                    continue;
                }
                listModel.addElement(username);
                change = true;
            }
            if (change) {
                jList.setModel(listModel);
            }
        }
        GroupListRequest groupListRequest = new GroupListRequest(hostUserName);
        Response groupResponse = ConnectionUtil.makeConnection(groupListRequest);
        if (groupResponse.getType().equals(ResponseType.GroupList)) {
            DefaultListModel<Group> groupListModel = (DefaultListModel<Group>) groupJList.getModel();
            GroupListResponse groupListResponse = (GroupListResponse) groupResponse;
            groupList= groupListResponse.getGroupList();
            boolean groupChange = false;
            for (Group group : groupList) {
                if (isExistedGroup(group, groupListModel.elements())) {
                    continue;
                }
                groupListModel.addElement(group);
                groupChange = true;
            }
            if (groupChange) {
                groupJList.setModel(groupListModel);
            }
        }
    }

    private static boolean isExistedGroup(Group group, Enumeration<Group> groupsInList) {
        while (groupsInList.hasMoreElements()) {
            if (groupsInList.nextElement().getUuid().equals(group.getUuid())) {
                return true;
            }
        }
        return false;
    }

    public String getFriendName() {
        return this.friendNameField.getText();
    }
    public String getGroupFriendName(){return this.groupFriendNameField.getText();}
    public String getAddGroupName(){return  this.groupNameField.getText();}
    public UUID getGroupid(){return this.groupid;}

}
